<html>
<head>
<title>CpcPaChi - Version 0.03</title>
<style type="text/css">
span {
	font-family: 'Courier New';
	font-size: 10pt;
	color: #000000;
}
.sc0 {
	color: #808080;
}
.sc3 {
	color: #008080;
}
.sc4 {
	color: #FF8000;
}
.sc5 {
	font-weight: bold;
	color: #0000FF;
}
.sc7 {
	color: #808080;
}
.sc9 {
	color: #804000;
}
.sc10 {
	font-weight: bold;
	color: #000080;
}
.sc11 {
}
</style>
</head>
<body>
<h2>Un compilador sencillo paso a paso (3)</h2>

<p align="right">(Volver al <a href="doc.html">&iacute;ndice</a>) </p>

<p>Este tercer acercamiento va a incluir un primer analizador l&eacute;xico, que se encargue de extraer la informaci&oacute;n que le pidamos del fichero de entrada.</p>

<p>La intenci&oacute;n es tener funciones como "obtenerIdentificador" o como "obtenerEntero", que simplifiquen el an&aacute;lisis del programa fuente.</p>

<p>Por ejemplo, el an&aacute;lisis de "LOCATE", que debe estar seguido por un par&eacute;ntesis abierto, un n&uacute;mero entero, una coma, otro n&uacute;mero entero y un par&eacute;ntesis cerrado, antes era totalmente artesanal:</p>

<pre>
(* Leo X: 1 o 2 letras *)
posicion := 8;
x := ord(orden[posicion])-ord('0');
posicion := posicion + 1;
if orden[posicion] <> ',' then
  begin
  x := x*10 + ord(orden[posicion])-ord('0');
  posicion := posicion + 1;
  end;
(* Tras la coma esta Y: 1 o 2 letras *)
posicion := posicion + 1;
y := ord(orden[posicion])-ord('0');
posicion := posicion + 1;
if orden[posicion] <> ')' then
  begin
  y := y*10 + ord(orden[posicion])-ord('0');
  posicion := posicion + 1;
  end;
</pre>

<p>y ahora ser&aacute; algo mucho m&aacute;s legible:</p>

<pre>
leerSimbolo('(');
val(obtenerEntero,x,codError);
leerSimbolo(',');
val(obtenerEntero,y,codError);
leerSimbolo(')');
</pre>


<p>Las posibilidades de nuestro analizador l&eacute;xico son pocas por ahora, pero suficientes para lo que necesitamos en este momento:</p>

<ul>
  <li>Una funci&oacute;n "obtenerLetra", que devuelve una letra (un "char") del fichero de entrada. Internamente se lee de linea en linea: cada letra se toma de la l&iacute;nea actual, o se pide una nueva l&iacute;nea si no quedan m&aacute;s letras en la actual.</li>
  <li>Una funci&oacute;n "obtenerIdentificador", que devuelve una cadena ("string") formada por un conjunto de letras de la A a la Z (en "el mundo real" se suelen permitir tambi&eacute;n cifras num&eacute;ricas dentro de un identificador, pero a nosotros nos basta as&iacute; por ahora).</li>
  <li>Una funci&oacute;n "obtenerEntero", que devuelve un n&uacute;mero entero, como cadena ("string") formada por un conjunto de cifras del 0 al 9.</li>
  <li>Una funci&oacute;n "leerSimbolo", que intenta leer un cierto s&iacute;mbolo desde la entrada, y sale con un mensaje de error si no lo encuentra. Es nuestra primera ayuda para el an&aacute;lisis sint&aacute;ctico, del que hablaremos pronto: ciertos s&iacute;mbolos deben aparecer en un cierto orden (por ejemplo, despu&eacute;s de LOCATE debe hacer un par&eacute;ntesis abierto, un n&uacute;mero entero, una coma...) y esta funci&oacute;n nos servir&aacute; para comprobar que es as&iacute;.</li>
</ul>

<p><br />El c&oacute;digo fuente de este primer analizador l&eacute;xico ser&aacute;</p>

<pre><span class="sc5">unit</span><span class="sc0"> </span><span class="sc11">upachil</span><span class="sc10">;</span><span class="sc0">

</span><span class="sc3">(* cpcPaChi - Un compilador de Pascal chiquitito para CPC
   Por Nacho Cabanes

   uPachiL - unidad "Lexer" (analizador lexico)

   Versiones hasta la fecha:

   Num.   Fecha       Cambios
   ---------------------------------------------------
   0.03  25-Mar-2008  Primera version del analizador lexico:
                      es capaz de devolver un identificador,
                      un entero y de comprobar si el siguiente
                      simbolo es uno prefijado;
                      lee linea a linea del fichero de entrada
*)</span><span class="sc0">


</span><span class="sc5">interface</span><span class="sc0">

  </span><span class="sc5">function</span><span class="sc0"> </span><span class="sc11">abrirFicheroEntrada</span><span class="sc10">(</span><span class="sc11">nombre</span><span class="sc10">:</span><span class="sc0"> </span><span class="sc5">string</span><span class="sc10">):</span><span class="sc0"> </span><span class="sc11">boolean</span><span class="sc10">;</span><span class="sc0">
  </span><span class="sc5">function</span><span class="sc0"> </span><span class="sc11">obtenerLetra</span><span class="sc10">:</span><span class="sc0"> </span><span class="sc11">char</span><span class="sc10">;</span><span class="sc0">
  </span><span class="sc5">function</span><span class="sc0"> </span><span class="sc11">obtenerIdentificador</span><span class="sc10">:</span><span class="sc0"> </span><span class="sc5">string</span><span class="sc10">;</span><span class="sc0">
  </span><span class="sc5">function</span><span class="sc0"> </span><span class="sc11">obtenerEntero</span><span class="sc10">:</span><span class="sc0"> </span><span class="sc5">string</span><span class="sc10">;</span><span class="sc0">
  </span><span class="sc5">procedure</span><span class="sc0"> </span><span class="sc11">cerrarFicheroEntrada</span><span class="sc10">;</span><span class="sc0">
  </span><span class="sc5">procedure</span><span class="sc0"> </span><span class="sc11">leerSimbolo</span><span class="sc10">(</span><span class="sc11">simbolo</span><span class="sc10">:</span><span class="sc11">char</span><span class="sc10">);</span><span class="sc0">

  </span><span class="sc5">var</span><span class="sc0">
    </span><span class="sc11">lineaDeEntrada</span><span class="sc10">:</span><span class="sc0"> </span><span class="sc5">string</span><span class="sc10">;</span><span class="sc0">
    </span><span class="sc11">finFicheroEntrada</span><span class="sc10">:</span><span class="sc0"> </span><span class="sc11">boolean</span><span class="sc10">;</span><span class="sc0">

</span><span class="sc5">implementation</span><span class="sc0">

</span><span class="sc5">var</span><span class="sc0">
  </span><span class="sc11">ficheroEntrada</span><span class="sc10">:</span><span class="sc0"> </span><span class="sc11">text</span><span class="sc10">;</span><span class="sc0">
  </span><span class="sc11">posicionLineaActual</span><span class="sc10">:</span><span class="sc0"> </span><span class="sc11">integer</span><span class="sc10">;</span><span class="sc0">


</span><span class="sc3">(* Abre el fichero de entrada. Devuelve FALSE si no se
ha podido *)</span><span class="sc0">
</span><span class="sc5">function</span><span class="sc0"> </span><span class="sc11">abrirFicheroEntrada</span><span class="sc10">(</span><span class="sc11">nombre</span><span class="sc10">:</span><span class="sc0"> </span><span class="sc5">string</span><span class="sc10">):</span><span class="sc0"> </span><span class="sc11">boolean</span><span class="sc10">;</span><span class="sc0">
</span><span class="sc5">begin</span><span class="sc0">
   </span><span class="sc11">assign</span><span class="sc10">(</span><span class="sc0"> </span><span class="sc11">ficheroEntrada</span><span class="sc10">,</span><span class="sc0"> </span><span class="sc11">nombre</span><span class="sc0"> </span><span class="sc10">);</span><span class="sc0">
   </span><span class="sc9">{$I-}</span><span class="sc0">
   </span><span class="sc11">reset</span><span class="sc10">(</span><span class="sc0"> </span><span class="sc11">ficheroEntrada</span><span class="sc0"> </span><span class="sc10">);</span><span class="sc0">
   </span><span class="sc9">{$I+}</span><span class="sc0">
   </span><span class="sc11">posicionLineaActual</span><span class="sc0"> </span><span class="sc10">:=</span><span class="sc0"> </span><span class="sc4">0</span><span class="sc10">;</span><span class="sc0">

   </span><span class="sc5">if</span><span class="sc0"> </span><span class="sc11">ioResult</span><span class="sc0"> </span><span class="sc10">=</span><span class="sc0"> </span><span class="sc4">0</span><span class="sc0"> </span><span class="sc5">then</span><span class="sc0">
     </span><span class="sc5">begin</span><span class="sc0">
     </span><span class="sc11">finFicheroEntrada</span><span class="sc0"> </span><span class="sc10">:=</span><span class="sc0"> </span><span class="sc11">false</span><span class="sc10">;</span><span class="sc0">
     </span><span class="sc11">abrirFicheroEntrada</span><span class="sc0"> </span><span class="sc10">:=</span><span class="sc0"> </span><span class="sc11">true</span><span class="sc10">;</span><span class="sc0">
     </span><span class="sc5">end</span><span class="sc0">
   </span><span class="sc5">else</span><span class="sc0">
     </span><span class="sc5">begin</span><span class="sc0">
     </span><span class="sc11">finFicheroEntrada</span><span class="sc0"> </span><span class="sc10">:=</span><span class="sc0"> </span><span class="sc11">true</span><span class="sc10">;</span><span class="sc0">
     </span><span class="sc11">abrirFicheroEntrada</span><span class="sc0"> </span><span class="sc10">:=</span><span class="sc0"> </span><span class="sc11">false</span><span class="sc10">;</span><span class="sc0">
     </span><span class="sc5">end</span><span class="sc10">;</span><span class="sc0">
</span><span class="sc5">end</span><span class="sc10">;</span><span class="sc0">


</span><span class="sc3">(* Cerrar fichero de entrada (al final del analisis) *)</span><span class="sc0">
</span><span class="sc5">procedure</span><span class="sc0"> </span><span class="sc11">cerrarFicheroEntrada</span><span class="sc10">;</span><span class="sc0">
</span><span class="sc5">begin</span><span class="sc0">
  </span><span class="sc11">close</span><span class="sc10">(</span><span class="sc11">ficheroEntrada</span><span class="sc10">);</span><span class="sc0">
</span><span class="sc5">end</span><span class="sc10">;</span><span class="sc0">

</span><span class="sc3">(* Lee una linea del fichero de entrada. Solo para uso interno del lexer *)</span><span class="sc0">
</span><span class="sc5">procedure</span><span class="sc0"> </span><span class="sc11">leerLinea</span><span class="sc10">;</span><span class="sc0">
</span><span class="sc5">begin</span><span class="sc0">
  </span><span class="sc11">readln</span><span class="sc10">(</span><span class="sc0"> </span><span class="sc11">ficheroEntrada</span><span class="sc10">,</span><span class="sc0"> </span><span class="sc11">lineaDeEntrada</span><span class="sc0"> </span><span class="sc10">);</span><span class="sc0">
  </span><span class="sc5">if</span><span class="sc0"> </span><span class="sc11">eof</span><span class="sc10">(</span><span class="sc11">ficheroEntrada</span><span class="sc10">)</span><span class="sc0"> </span><span class="sc5">then</span><span class="sc0">
    </span><span class="sc11">finFicheroEntrada</span><span class="sc0"> </span><span class="sc10">:=</span><span class="sc0"> </span><span class="sc11">true</span><span class="sc10">;</span><span class="sc0">
</span><span class="sc5">end</span><span class="sc10">;</span><span class="sc0">

</span><span class="sc3">(* Obtiene una letra del fichero. Se apoya en leerLinea: toma la
siguiente letra de "LineaDeEntrada", o lee otra linea del fichero
si la actual ha terminado *)</span><span class="sc0">
</span><span class="sc5">function</span><span class="sc0"> </span><span class="sc11">obtenerLetra</span><span class="sc10">:</span><span class="sc0"> </span><span class="sc11">char</span><span class="sc10">;</span><span class="sc0">
</span><span class="sc5">begin</span><span class="sc0">
  </span><span class="sc5">if</span><span class="sc0"> </span><span class="sc11">posicionLineaActual</span><span class="sc0"> </span><span class="sc10">&gt;=</span><span class="sc0"> </span><span class="sc11">length</span><span class="sc10">(</span><span class="sc11">lineaDeEntrada</span><span class="sc10">)</span><span class="sc0"> </span><span class="sc5">then</span><span class="sc0">
    </span><span class="sc5">begin</span><span class="sc0">
    </span><span class="sc11">leerLinea</span><span class="sc10">;</span><span class="sc0">
    </span><span class="sc11">posicionLineaActual</span><span class="sc0"> </span><span class="sc10">:=</span><span class="sc0"> </span><span class="sc4">0</span><span class="sc10">;</span><span class="sc0">
    </span><span class="sc11">obtenerLetra</span><span class="sc0"> </span><span class="sc10">:=</span><span class="sc0"> </span><span class="sc7">' '</span><span class="sc10">;</span><span class="sc0">
    </span><span class="sc5">end</span><span class="sc0">
  </span><span class="sc5">else</span><span class="sc0">
    </span><span class="sc5">begin</span><span class="sc0">
    </span><span class="sc11">inc</span><span class="sc10">(</span><span class="sc11">posicionLineaActual</span><span class="sc10">);</span><span class="sc0">
    </span><span class="sc11">obtenerLetra</span><span class="sc0"> </span><span class="sc10">:=</span><span class="sc0"> </span><span class="sc11">lineaDeEntrada</span><span class="sc10">[</span><span class="sc11">posicionLineaActual</span><span class="sc10">];</span><span class="sc0">
    </span><span class="sc5">end</span><span class="sc10">;</span><span class="sc0">
</span><span class="sc5">end</span><span class="sc10">;</span><span class="sc0">

</span><span class="sc3">(* Obtiene un identificador: devuelve una secuencia de letras *)</span><span class="sc0">
</span><span class="sc5">function</span><span class="sc0"> </span><span class="sc11">obtenerIdentificador</span><span class="sc10">:</span><span class="sc0"> </span><span class="sc5">string</span><span class="sc10">;</span><span class="sc0">
</span><span class="sc5">var</span><span class="sc0">
  </span><span class="sc11">lexema</span><span class="sc10">:</span><span class="sc0"> </span><span class="sc5">string</span><span class="sc10">;</span><span class="sc0">
  </span><span class="sc11">letra</span><span class="sc10">:</span><span class="sc0"> </span><span class="sc11">char</span><span class="sc10">;</span><span class="sc0">
</span><span class="sc5">begin</span><span class="sc0">
  </span><span class="sc11">lexema</span><span class="sc0"> </span><span class="sc10">:=</span><span class="sc0"> </span><span class="sc7">''</span><span class="sc10">;</span><span class="sc0">
  </span><span class="sc11">letra</span><span class="sc0"> </span><span class="sc10">:=</span><span class="sc0"> </span><span class="sc11">obtenerLetra</span><span class="sc10">;</span><span class="sc0">
  </span><span class="sc5">while</span><span class="sc0"> </span><span class="sc11">upcase</span><span class="sc10">(</span><span class="sc11">letra</span><span class="sc10">)</span><span class="sc0"> </span><span class="sc5">in</span><span class="sc0"> </span><span class="sc10">[</span><span class="sc7">'A'</span><span class="sc10">..</span><span class="sc7">'Z'</span><span class="sc10">]</span><span class="sc0"> </span><span class="sc5">do</span><span class="sc0">
    </span><span class="sc5">begin</span><span class="sc0">
    </span><span class="sc11">lexema</span><span class="sc0"> </span><span class="sc10">:=</span><span class="sc0"> </span><span class="sc11">lexema</span><span class="sc0"> </span><span class="sc10">+</span><span class="sc0"> </span><span class="sc11">letra</span><span class="sc10">;</span><span class="sc0">
    </span><span class="sc11">letra</span><span class="sc0"> </span><span class="sc10">:=</span><span class="sc0"> </span><span class="sc11">obtenerLetra</span><span class="sc10">;</span><span class="sc0">
    </span><span class="sc5">end</span><span class="sc10">;</span><span class="sc0">
  </span><span class="sc3">(* He leido uno de mas, asi que retrocedo *)</span><span class="sc0">
  </span><span class="sc5">if</span><span class="sc0"> </span><span class="sc11">posicionLineaActual</span><span class="sc0"> </span><span class="sc10">&gt;</span><span class="sc0"> </span><span class="sc4">0</span><span class="sc0"> </span><span class="sc5">then</span><span class="sc0">
    </span><span class="sc11">dec</span><span class="sc10">(</span><span class="sc11">posicionLineaActual</span><span class="sc10">);</span><span class="sc0">
  </span><span class="sc11">obtenerIdentificador</span><span class="sc0"> </span><span class="sc10">:=</span><span class="sc0"> </span><span class="sc11">lexema</span><span class="sc10">;</span><span class="sc0">
</span><span class="sc5">end</span><span class="sc10">;</span><span class="sc0">


</span><span class="sc3">(* Obtiene un entero: devuelve una secuencia de cifras *)</span><span class="sc0">
</span><span class="sc5">function</span><span class="sc0"> </span><span class="sc11">obtenerEntero</span><span class="sc10">:</span><span class="sc0"> </span><span class="sc5">string</span><span class="sc10">;</span><span class="sc0">
</span><span class="sc5">var</span><span class="sc0">
  </span><span class="sc11">lexema</span><span class="sc10">:</span><span class="sc0"> </span><span class="sc5">string</span><span class="sc10">;</span><span class="sc0">
  </span><span class="sc11">letra</span><span class="sc10">:</span><span class="sc0"> </span><span class="sc11">char</span><span class="sc10">;</span><span class="sc0">
</span><span class="sc5">begin</span><span class="sc0">
  </span><span class="sc11">lexema</span><span class="sc0"> </span><span class="sc10">:=</span><span class="sc0"> </span><span class="sc7">''</span><span class="sc10">;</span><span class="sc0">
  </span><span class="sc11">letra</span><span class="sc0"> </span><span class="sc10">:=</span><span class="sc0"> </span><span class="sc11">obtenerLetra</span><span class="sc10">;</span><span class="sc0">
  </span><span class="sc5">while</span><span class="sc0"> </span><span class="sc11">upcase</span><span class="sc10">(</span><span class="sc11">letra</span><span class="sc10">)</span><span class="sc0"> </span><span class="sc5">in</span><span class="sc0"> </span><span class="sc10">[</span><span class="sc7">'0'</span><span class="sc10">..</span><span class="sc7">'9'</span><span class="sc10">]</span><span class="sc0"> </span><span class="sc5">do</span><span class="sc0">
    </span><span class="sc5">begin</span><span class="sc0">
    </span><span class="sc11">lexema</span><span class="sc0"> </span><span class="sc10">:=</span><span class="sc0"> </span><span class="sc11">lexema</span><span class="sc0"> </span><span class="sc10">+</span><span class="sc0"> </span><span class="sc11">letra</span><span class="sc10">;</span><span class="sc0">
    </span><span class="sc11">letra</span><span class="sc0"> </span><span class="sc10">:=</span><span class="sc0"> </span><span class="sc11">obtenerLetra</span><span class="sc10">;</span><span class="sc0">
    </span><span class="sc5">end</span><span class="sc10">;</span><span class="sc0">
  </span><span class="sc3">(* He leido uno de mas, asi que retrocedo *)</span><span class="sc0">
  </span><span class="sc5">if</span><span class="sc0"> </span><span class="sc11">posicionLineaActual</span><span class="sc0"> </span><span class="sc10">&gt;</span><span class="sc0"> </span><span class="sc4">0</span><span class="sc0"> </span><span class="sc5">then</span><span class="sc0">
    </span><span class="sc11">dec</span><span class="sc10">(</span><span class="sc11">posicionLineaActual</span><span class="sc10">);</span><span class="sc0">
  </span><span class="sc11">obtenerEntero</span><span class="sc0"> </span><span class="sc10">:=</span><span class="sc0"> </span><span class="sc11">lexema</span><span class="sc10">;</span><span class="sc0">
</span><span class="sc5">end</span><span class="sc10">;</span><span class="sc0">


</span><span class="sc3">(* Obtiene un identificador: devuelve una secuencia de letras *)</span><span class="sc0">
</span><span class="sc5">procedure</span><span class="sc0"> </span><span class="sc11">leerSimbolo</span><span class="sc10">(</span><span class="sc11">simbolo</span><span class="sc10">:</span><span class="sc11">char</span><span class="sc10">);</span><span class="sc0">
</span><span class="sc5">var</span><span class="sc0">
  </span><span class="sc11">letra</span><span class="sc10">:</span><span class="sc0"> </span><span class="sc11">char</span><span class="sc10">;</span><span class="sc0">
</span><span class="sc5">begin</span><span class="sc0">
  </span><span class="sc11">letra</span><span class="sc0"> </span><span class="sc10">:=</span><span class="sc0"> </span><span class="sc11">obtenerLetra</span><span class="sc10">;</span><span class="sc0">
  </span><span class="sc5">if</span><span class="sc0"> </span><span class="sc11">letra</span><span class="sc0"> </span><span class="sc10">&lt;&gt;</span><span class="sc0"> </span><span class="sc11">simbolo</span><span class="sc0"> </span><span class="sc5">then</span><span class="sc0">
    </span><span class="sc5">begin</span><span class="sc0">
    </span><span class="sc11">writeln</span><span class="sc10">(</span><span class="sc7">'Se esperaba '</span><span class="sc10">,</span><span class="sc11">simbolo</span><span class="sc10">,</span><span class="sc7">' y se ha encontrado '</span><span class="sc10">,</span><span class="sc11">letra</span><span class="sc10">);</span><span class="sc0">
    </span><span class="sc11">halt</span><span class="sc10">;</span><span class="sc0">
    </span><span class="sc5">end</span><span class="sc10">;</span><span class="sc0">
</span><span class="sc5">end</span><span class="sc10">;</span><span class="sc0">


</span><span class="sc5">begin</span><span class="sc0">
</span><span class="sc5">end.</span><span class="sc0">
</span>
</pre>





<p><br />Y el c&oacute;digo fuente del programa principal ser&aacute;:</p>


<pre><span class="sc5">program</span><span class="sc0"> </span><span class="sc11">cpcPaChi</span><span class="sc10">;</span><span class="sc0">

</span><span class="sc3">(* Chi - Un compilador de Pascal chiquitito para CPC
   Por Nacho Cabanes - Version 0.03

   Versiones hasta la fecha:

   Num.   Fecha       Cambios
   ---------------------------------------------------
   0.03  25-Mar-2008  Creado un analizador lexico independiente
                      (en la unit "uPaChiL")

   0.02  23-Mar-2008  Admite CLS, LOCATE, WRITECHAR,
                      que lee desde fichero. Solo permite
                      una orden en cada linea, con formato fijo

   0.01  21-Mar-2008  Preliminar: solo acepta CLS por teclado
                      y genera el codigo correspondiente

*)</span><span class="sc0">

</span><span class="sc5">uses</span><span class="sc0"> </span><span class="sc11">upachil</span><span class="sc10">;</span><span class="sc0">  </span><span class="sc3">(* Analizador lexico *)</span><span class="sc0">

</span><span class="sc5">const</span><span class="sc0">
  </span><span class="sc11">lineaActual</span><span class="sc10">:</span><span class="sc0"> </span><span class="sc11">integer</span><span class="sc0"> </span><span class="sc10">=</span><span class="sc0"> </span><span class="sc4">10</span><span class="sc10">;</span><span class="sc0">
  </span><span class="sc11">longitudTotal</span><span class="sc10">:</span><span class="sc0"> </span><span class="sc11">integer</span><span class="sc0"> </span><span class="sc10">=</span><span class="sc0"> </span><span class="sc4">0</span><span class="sc10">;</span><span class="sc0">

</span><span class="sc5">var</span><span class="sc0">
  </span><span class="sc11">ficheroDestino</span><span class="sc10">:</span><span class="sc0"> </span><span class="sc11">text</span><span class="sc10">;</span><span class="sc0">
  </span><span class="sc11">nombreOrigen</span><span class="sc10">,</span><span class="sc0"> </span><span class="sc11">nombreDestino</span><span class="sc10">:</span><span class="sc0"> </span><span class="sc5">string</span><span class="sc10">;</span><span class="sc0">
  </span><span class="sc11">orden</span><span class="sc10">:</span><span class="sc0"> </span><span class="sc5">string</span><span class="sc10">;</span><span class="sc0">

</span><span class="sc3">(* Analiza las opciones que teclee el usuario. Por ahora,
solo el nombre del fichero a compilar *)</span><span class="sc0">
</span><span class="sc5">procedure</span><span class="sc0"> </span><span class="sc11">analizarOpciones</span><span class="sc10">;</span><span class="sc0">
</span><span class="sc5">begin</span><span class="sc0">
  </span><span class="sc5">if</span><span class="sc0"> </span><span class="sc11">paramcount</span><span class="sc0"> </span><span class="sc10">&gt;=</span><span class="sc0"> </span><span class="sc4">1</span><span class="sc0"> </span><span class="sc5">then</span><span class="sc0">
    </span><span class="sc11">nombreOrigen</span><span class="sc0"> </span><span class="sc10">:=</span><span class="sc0"> </span><span class="sc11">paramstr</span><span class="sc10">(</span><span class="sc4">1</span><span class="sc10">)</span><span class="sc0">
  </span><span class="sc5">else</span><span class="sc0">
    </span><span class="sc5">begin</span><span class="sc0">
    </span><span class="sc11">writeln</span><span class="sc10">(</span><span class="sc7">'No se ha indicado el nombre del fichero'</span><span class="sc10">);</span><span class="sc0">
    </span><span class="sc11">halt</span><span class="sc10">;</span><span class="sc0">
    </span><span class="sc5">end</span><span class="sc10">;</span><span class="sc0">
  </span><span class="sc11">abrirFicheroEntrada</span><span class="sc10">(</span><span class="sc0"> </span><span class="sc11">nombreOrigen</span><span class="sc0"> </span><span class="sc10">);</span><span class="sc0">
  </span><span class="sc11">nombreDestino</span><span class="sc0"> </span><span class="sc10">:=</span><span class="sc0"> </span><span class="sc7">'salida.bas'</span><span class="sc10">;</span><span class="sc0">
  </span><span class="sc11">assign</span><span class="sc10">(</span><span class="sc0"> </span><span class="sc11">ficheroDestino</span><span class="sc10">,</span><span class="sc0"> </span><span class="sc11">nombreDestino</span><span class="sc0"> </span><span class="sc10">);</span><span class="sc0">
  </span><span class="sc11">rewrite</span><span class="sc10">(</span><span class="sc0"> </span><span class="sc11">ficheroDestino</span><span class="sc0"> </span><span class="sc10">);</span><span class="sc0">
</span><span class="sc5">end</span><span class="sc10">;</span><span class="sc0">


</span><span class="sc3">(* Analiza la orden que el usuario ha dado, y sale con un mensaje
de error si es incorrecta *)</span><span class="sc0">
</span><span class="sc5">procedure</span><span class="sc0"> </span><span class="sc11">analizarUnaOrden</span><span class="sc10">;</span><span class="sc0">
</span><span class="sc5">begin</span><span class="sc0">
  </span><span class="sc11">orden</span><span class="sc0"> </span><span class="sc10">:=</span><span class="sc0"> </span><span class="sc11">upcase</span><span class="sc10">(</span><span class="sc11">obtenerIdentificador</span><span class="sc10">);</span><span class="sc0">
  </span><span class="sc5">if</span><span class="sc0"> </span><span class="sc10">(</span><span class="sc11">orden</span><span class="sc0"> </span><span class="sc10">&lt;&gt;</span><span class="sc0"> </span><span class="sc7">'CLS'</span><span class="sc10">)</span><span class="sc0">
      </span><span class="sc5">and</span><span class="sc0"> </span><span class="sc10">(</span><span class="sc11">orden</span><span class="sc0"> </span><span class="sc10">&lt;&gt;</span><span class="sc0"> </span><span class="sc7">'LOCATE'</span><span class="sc10">)</span><span class="sc0">
      </span><span class="sc5">and</span><span class="sc0"> </span><span class="sc10">(</span><span class="sc11">orden</span><span class="sc0"> </span><span class="sc10">&lt;&gt;</span><span class="sc0"> </span><span class="sc7">'WRITECHAR'</span><span class="sc10">)</span><span class="sc0">
      </span><span class="sc5">and</span><span class="sc0"> </span><span class="sc10">(</span><span class="sc11">orden</span><span class="sc0"> </span><span class="sc10">&lt;&gt;</span><span class="sc0"> </span><span class="sc7">''</span><span class="sc10">)</span><span class="sc0"> </span><span class="sc5">then</span><span class="sc0">
    </span><span class="sc5">begin</span><span class="sc0">
    </span><span class="sc11">writeln</span><span class="sc10">(</span><span class="sc7">'Error: orden no reconocida. Se esperaba: CLS, LOCATE o WRITECHAR'</span><span class="sc10">);</span><span class="sc0">
    </span><span class="sc3">(*halt;*)</span><span class="sc0">
    </span><span class="sc5">end</span><span class="sc10">;</span><span class="sc0">
</span><span class="sc5">end</span><span class="sc10">;</span><span class="sc0">


</span><span class="sc3">(* Genera el codigo de destino: codigo maquina de Amstrad CPC
dentro de un cargador en Basic *)</span><span class="sc0">
</span><span class="sc5">procedure</span><span class="sc0"> </span><span class="sc11">generarCodigoUnaOrden</span><span class="sc10">;</span><span class="sc0">
</span><span class="sc5">var</span><span class="sc0">
  </span><span class="sc11">x</span><span class="sc10">,</span><span class="sc0"> </span><span class="sc11">y</span><span class="sc10">:</span><span class="sc0"> </span><span class="sc11">byte</span><span class="sc10">;</span><span class="sc0">
  </span><span class="sc11">letra</span><span class="sc10">:</span><span class="sc0"> </span><span class="sc11">char</span><span class="sc10">;</span><span class="sc0">
  </span><span class="sc11">codError</span><span class="sc10">:</span><span class="sc0"> </span><span class="sc11">integer</span><span class="sc10">;</span><span class="sc0">
</span><span class="sc5">begin</span><span class="sc0">
  </span><span class="sc5">if</span><span class="sc0"> </span><span class="sc11">orden</span><span class="sc0"> </span><span class="sc10">=</span><span class="sc0"> </span><span class="sc7">'CLS'</span><span class="sc0"> </span><span class="sc5">then</span><span class="sc0">
    </span><span class="sc5">begin</span><span class="sc0">
    </span><span class="sc11">writeln</span><span class="sc10">(</span><span class="sc0"> </span><span class="sc11">ficheroDestino</span><span class="sc10">,</span><span class="sc0"> </span><span class="sc11">lineaActual</span><span class="sc10">,</span><span class="sc7">' DATA CD,6C,BB: '' CALL &amp;BB6C - CLS'</span><span class="sc0"> </span><span class="sc10">);</span><span class="sc0">
    </span><span class="sc11">lineaActual</span><span class="sc0"> </span><span class="sc10">:=</span><span class="sc0"> </span><span class="sc11">lineaActual</span><span class="sc0"> </span><span class="sc10">+</span><span class="sc0"> </span><span class="sc4">10</span><span class="sc10">;</span><span class="sc0">
    </span><span class="sc11">longitudTotal</span><span class="sc0"> </span><span class="sc10">:=</span><span class="sc0"> </span><span class="sc11">longitudTotal</span><span class="sc0"> </span><span class="sc10">+</span><span class="sc0"> </span><span class="sc4">3</span><span class="sc10">;</span><span class="sc0">
    </span><span class="sc5">end</span><span class="sc10">;</span><span class="sc0">
  </span><span class="sc5">if</span><span class="sc0"> </span><span class="sc11">orden</span><span class="sc0"> </span><span class="sc10">=</span><span class="sc0"> </span><span class="sc7">'WRITECHAR'</span><span class="sc0"> </span><span class="sc5">then</span><span class="sc0">
    </span><span class="sc5">begin</span><span class="sc0">
    </span><span class="sc11">leerSimbolo</span><span class="sc10">(</span><span class="sc7">'('</span><span class="sc10">);</span><span class="sc0">
    </span><span class="sc11">leerSimbolo</span><span class="sc10">(</span><span class="sc7">''''</span><span class="sc10">);</span><span class="sc0">
    </span><span class="sc11">letra</span><span class="sc0"> </span><span class="sc10">:=</span><span class="sc0"> </span><span class="sc11">obtenerLetra</span><span class="sc10">;</span><span class="sc0">
    </span><span class="sc11">leerSimbolo</span><span class="sc10">(</span><span class="sc7">''''</span><span class="sc10">);</span><span class="sc0">
    </span><span class="sc11">leerSimbolo</span><span class="sc10">(</span><span class="sc7">')'</span><span class="sc10">);</span><span class="sc0">
    </span><span class="sc11">writeln</span><span class="sc10">(</span><span class="sc0"> </span><span class="sc11">ficheroDestino</span><span class="sc10">,</span><span class="sc0"> </span><span class="sc11">lineaActual</span><span class="sc10">,</span><span class="sc7">' DATA 3E,'</span><span class="sc10">,</span><span class="sc0">
      </span><span class="sc11">hexStr</span><span class="sc10">(</span><span class="sc11">ord</span><span class="sc10">(</span><span class="sc11">letra</span><span class="sc10">),</span><span class="sc4">2</span><span class="sc10">),</span><span class="sc0"> </span><span class="sc7">': '' LD A, "'</span><span class="sc10">,</span><span class="sc11">letra</span><span class="sc10">,</span><span class="sc0"> </span><span class="sc7">'"'</span><span class="sc0"> </span><span class="sc10">);</span><span class="sc0">
    </span><span class="sc11">lineaActual</span><span class="sc0"> </span><span class="sc10">:=</span><span class="sc0"> </span><span class="sc11">lineaActual</span><span class="sc0"> </span><span class="sc10">+</span><span class="sc0"> </span><span class="sc4">10</span><span class="sc10">;</span><span class="sc0">
    </span><span class="sc11">writeln</span><span class="sc10">(</span><span class="sc0"> </span><span class="sc11">ficheroDestino</span><span class="sc10">,</span><span class="sc0"> </span><span class="sc11">lineaActual</span><span class="sc10">,</span><span class="sc7">' DATA CD,5A,BB: '' CALL &amp;BB5A - WRITECHAR'</span><span class="sc0"> </span><span class="sc10">);</span><span class="sc0">
    </span><span class="sc11">lineaActual</span><span class="sc0"> </span><span class="sc10">:=</span><span class="sc0"> </span><span class="sc11">lineaActual</span><span class="sc0"> </span><span class="sc10">+</span><span class="sc0"> </span><span class="sc4">10</span><span class="sc10">;</span><span class="sc0">
    </span><span class="sc11">longitudTotal</span><span class="sc0"> </span><span class="sc10">:=</span><span class="sc0"> </span><span class="sc11">longitudTotal</span><span class="sc0"> </span><span class="sc10">+</span><span class="sc0"> </span><span class="sc4">5</span><span class="sc10">;</span><span class="sc0">
    </span><span class="sc5">end</span><span class="sc10">;</span><span class="sc0">
  </span><span class="sc5">if</span><span class="sc0"> </span><span class="sc11">orden</span><span class="sc0"> </span><span class="sc10">=</span><span class="sc0"> </span><span class="sc7">'LOCATE'</span><span class="sc0"> </span><span class="sc5">then</span><span class="sc0">
    </span><span class="sc5">begin</span><span class="sc0">
    </span><span class="sc11">leerSimbolo</span><span class="sc10">(</span><span class="sc7">'('</span><span class="sc10">);</span><span class="sc0">
    </span><span class="sc11">val</span><span class="sc10">(</span><span class="sc11">obtenerEntero</span><span class="sc10">,</span><span class="sc11">x</span><span class="sc10">,</span><span class="sc11">codError</span><span class="sc10">);</span><span class="sc0">
    </span><span class="sc11">leerSimbolo</span><span class="sc10">(</span><span class="sc7">','</span><span class="sc10">);</span><span class="sc0">
    </span><span class="sc11">val</span><span class="sc10">(</span><span class="sc11">obtenerEntero</span><span class="sc10">,</span><span class="sc11">y</span><span class="sc10">,</span><span class="sc11">codError</span><span class="sc10">);</span><span class="sc0">
    </span><span class="sc11">leerSimbolo</span><span class="sc10">(</span><span class="sc7">')'</span><span class="sc10">);</span><span class="sc0">
    </span><span class="sc11">writeln</span><span class="sc10">(</span><span class="sc0"> </span><span class="sc11">ficheroDestino</span><span class="sc10">,</span><span class="sc0"> </span><span class="sc11">lineaActual</span><span class="sc10">,</span><span class="sc7">' DATA 3E,'</span><span class="sc10">,</span><span class="sc0">
      </span><span class="sc11">hexStr</span><span class="sc10">(</span><span class="sc11">x</span><span class="sc10">,</span><span class="sc4">2</span><span class="sc10">),</span><span class="sc0"> </span><span class="sc7">': '' LD A, '</span><span class="sc10">,</span><span class="sc11">x</span><span class="sc0"> </span><span class="sc10">);</span><span class="sc0">
    </span><span class="sc11">lineaActual</span><span class="sc0"> </span><span class="sc10">:=</span><span class="sc0"> </span><span class="sc11">lineaActual</span><span class="sc0"> </span><span class="sc10">+</span><span class="sc0"> </span><span class="sc4">10</span><span class="sc10">;</span><span class="sc0">
    </span><span class="sc11">writeln</span><span class="sc10">(</span><span class="sc0"> </span><span class="sc11">ficheroDestino</span><span class="sc10">,</span><span class="sc0"> </span><span class="sc11">lineaActual</span><span class="sc10">,</span><span class="sc7">' DATA CD,6F,BB: '' CALL &amp;BB6F - CURSOR COLUMN'</span><span class="sc0"> </span><span class="sc10">);</span><span class="sc0">
    </span><span class="sc11">lineaActual</span><span class="sc0"> </span><span class="sc10">:=</span><span class="sc0"> </span><span class="sc11">lineaActual</span><span class="sc0"> </span><span class="sc10">+</span><span class="sc0"> </span><span class="sc4">10</span><span class="sc10">;</span><span class="sc0">
    </span><span class="sc11">writeln</span><span class="sc10">(</span><span class="sc0"> </span><span class="sc11">ficheroDestino</span><span class="sc10">,</span><span class="sc0"> </span><span class="sc11">lineaActual</span><span class="sc10">,</span><span class="sc7">' DATA 3E,'</span><span class="sc10">,</span><span class="sc0">
      </span><span class="sc11">hexStr</span><span class="sc10">(</span><span class="sc11">y</span><span class="sc10">,</span><span class="sc4">2</span><span class="sc10">),</span><span class="sc0"> </span><span class="sc7">': '' LD A, '</span><span class="sc10">,</span><span class="sc11">y</span><span class="sc0"> </span><span class="sc10">);</span><span class="sc0">
    </span><span class="sc11">lineaActual</span><span class="sc0"> </span><span class="sc10">:=</span><span class="sc0"> </span><span class="sc11">lineaActual</span><span class="sc0"> </span><span class="sc10">+</span><span class="sc0"> </span><span class="sc4">10</span><span class="sc10">;</span><span class="sc0">
    </span><span class="sc11">writeln</span><span class="sc10">(</span><span class="sc0"> </span><span class="sc11">ficheroDestino</span><span class="sc10">,</span><span class="sc0"> </span><span class="sc11">lineaActual</span><span class="sc10">,</span><span class="sc7">' DATA CD,72,BB: '' CALL &amp;BB72 - CURSOR ROW'</span><span class="sc0"> </span><span class="sc10">);</span><span class="sc0">
    </span><span class="sc3">(* 10 bytes *)</span><span class="sc0">
    </span><span class="sc11">lineaActual</span><span class="sc0"> </span><span class="sc10">:=</span><span class="sc0"> </span><span class="sc11">lineaActual</span><span class="sc0"> </span><span class="sc10">+</span><span class="sc0"> </span><span class="sc4">10</span><span class="sc10">;</span><span class="sc0">
    </span><span class="sc11">longitudTotal</span><span class="sc0"> </span><span class="sc10">:=</span><span class="sc0"> </span><span class="sc11">longitudTotal</span><span class="sc0"> </span><span class="sc10">+</span><span class="sc0"> </span><span class="sc4">10</span><span class="sc10">;</span><span class="sc0">
    </span><span class="sc5">end</span><span class="sc10">;</span><span class="sc0">
</span><span class="sc5">end</span><span class="sc10">;</span><span class="sc0">

</span><span class="sc3">(* Genera el codigo de destino final: cargador Basic *)</span><span class="sc0">
</span><span class="sc5">procedure</span><span class="sc0"> </span><span class="sc11">generarCodigoFinal</span><span class="sc10">;</span><span class="sc0">
</span><span class="sc5">begin</span><span class="sc0">
  </span><span class="sc11">cerrarFicheroEntrada</span><span class="sc10">;</span><span class="sc0">

  </span><span class="sc11">append</span><span class="sc10">(</span><span class="sc0"> </span><span class="sc11">ficheroDestino</span><span class="sc0"> </span><span class="sc10">);</span><span class="sc0">
  </span><span class="sc11">writeln</span><span class="sc10">(</span><span class="sc0"> </span><span class="sc11">ficheroDestino</span><span class="sc10">,</span><span class="sc0"> </span><span class="sc11">lineaActual</span><span class="sc10">,</span><span class="sc7">' DATA C9: '' RET'</span><span class="sc0"> </span><span class="sc10">);</span><span class="sc0">
  </span><span class="sc11">writeln</span><span class="sc10">(</span><span class="sc0"> </span><span class="sc11">ficheroDestino</span><span class="sc10">,</span><span class="sc0"> </span><span class="sc11">lineaActual</span><span class="sc10">+</span><span class="sc4">10</span><span class="sc10">,</span><span class="sc7">' longitud = '</span><span class="sc10">,</span><span class="sc11">longitudTotal</span><span class="sc0"> </span><span class="sc10">);</span><span class="sc0">
  </span><span class="sc11">writeln</span><span class="sc10">(</span><span class="sc0"> </span><span class="sc11">ficheroDestino</span><span class="sc10">,</span><span class="sc0"> </span><span class="sc11">lineaActual</span><span class="sc10">+</span><span class="sc4">20</span><span class="sc10">,</span><span class="sc7">' MEMORY 39999'</span><span class="sc0"> </span><span class="sc10">);</span><span class="sc0">
  </span><span class="sc11">writeln</span><span class="sc10">(</span><span class="sc0"> </span><span class="sc11">ficheroDestino</span><span class="sc10">,</span><span class="sc0"> </span><span class="sc11">lineaActual</span><span class="sc10">+</span><span class="sc4">30</span><span class="sc10">,</span><span class="sc7">' FOR n=40000 TO 40000+longitud'</span><span class="sc0"> </span><span class="sc10">);</span><span class="sc0">
  </span><span class="sc11">writeln</span><span class="sc10">(</span><span class="sc0"> </span><span class="sc11">ficheroDestino</span><span class="sc10">,</span><span class="sc0"> </span><span class="sc11">lineaActual</span><span class="sc10">+</span><span class="sc4">40</span><span class="sc10">,</span><span class="sc7">' READ a$:POKE n,VAL("&amp;"+a$)'</span><span class="sc0"> </span><span class="sc10">);</span><span class="sc0">
  </span><span class="sc11">writeln</span><span class="sc10">(</span><span class="sc0"> </span><span class="sc11">ficheroDestino</span><span class="sc10">,</span><span class="sc0"> </span><span class="sc11">lineaActual</span><span class="sc10">+</span><span class="sc4">50</span><span class="sc10">,</span><span class="sc7">' NEXT'</span><span class="sc0"> </span><span class="sc10">);</span><span class="sc0">
  </span><span class="sc11">writeln</span><span class="sc10">(</span><span class="sc0"> </span><span class="sc11">ficheroDestino</span><span class="sc10">,</span><span class="sc0"> </span><span class="sc11">lineaActual</span><span class="sc10">+</span><span class="sc4">60</span><span class="sc10">,</span><span class="sc7">' CALL 40000'</span><span class="sc0"> </span><span class="sc10">);</span><span class="sc0">
  </span><span class="sc11">close</span><span class="sc10">(</span><span class="sc11">ficheroDestino</span><span class="sc10">);</span><span class="sc0">
</span><span class="sc5">end</span><span class="sc10">;</span><span class="sc0">

</span><span class="sc3">(* Cuerpo del programa *)</span><span class="sc0">
</span><span class="sc5">begin</span><span class="sc0">
  </span><span class="sc11">analizarOpciones</span><span class="sc10">;</span><span class="sc0">
  </span><span class="sc5">while</span><span class="sc0"> </span><span class="sc5">not</span><span class="sc0"> </span><span class="sc11">finFicheroEntrada</span><span class="sc0"> </span><span class="sc5">do</span><span class="sc0">
    </span><span class="sc5">begin</span><span class="sc0">
    </span><span class="sc11">analizarUnaOrden</span><span class="sc10">;</span><span class="sc0">
    </span><span class="sc11">generarCodigoUnaOrden</span><span class="sc10">;</span><span class="sc0">
    </span><span class="sc5">end</span><span class="sc10">;</span><span class="sc0">
  </span><span class="sc11">generarCodigoFinal</span><span class="sc10">;</span><span class="sc0">
</span><span class="sc5">end.</span><span class="sc0">
</span>
</pre>


<p align="right">(Volver al <a href="doc.html">&iacute;ndice</a>) </p>
</body>
</html>
